home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cawf404.zip / device.c < prev    next >
C/C++ Source or Header  |  1993-12-07  |  10KB  |  416 lines

  1. /*
  2.  *    device.c -- cawf(1) output device support functions
  3.  */
  4.  
  5. /*
  6.  *    Copyright (c) 1991 Purdue University Research Foundation,
  7.  *    West Lafayette, Indiana 47907.  All rights reserved.
  8.  *
  9.  *    Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
  10.  *    University Computing Center.  Not derived from licensed software;
  11.  *    derived from awf(1) by Henry Spencer of the University of Toronto.
  12.  *
  13.  *    Permission is granted to anyone to use this software for any
  14.  *    purpose on any computer system, and to alter it and redistribute
  15.  *    it freely, subject to the following restrictions:
  16.  *
  17.  *    1. The author is not responsible for any consequences of use of
  18.  *       this software, even if they arise from flaws in it.
  19.  *
  20.  *    2. The origin of this software must not be misrepresented, either
  21.  *       by explicit claim or by omission.  Credits must appear in the
  22.  *       documentation.
  23.  *
  24.  *    3. Altered versions must be plainly marked as such, and must not
  25.  *       be misrepresented as being the original software.  Credits must
  26.  *       appear in the documentation.
  27.  *
  28.  *    4. This notice may not be removed or altered.
  29.  */
  30.  
  31. #include "cawf.h"
  32. #include <ctype.h>
  33.  
  34. _PROTOTYPE(static unsigned char *Convstr,(char *s, int *len));
  35. _PROTOTYPE(static int Convfont,(char *nm, char *s, char **fn,
  36.     unsigned char **fi));
  37.  
  38. #ifndef    UNIX
  39. #define    strcasecmp    strcmpi
  40. #endif
  41.  
  42.  
  43.  
  44. /*
  45.  * Convstr(s, len) - convert a string
  46.  */
  47.  
  48. static unsigned char *
  49. Convstr(s, len)
  50.     char *s;            /* input string */
  51.     int *len;            /* length of result */
  52. {
  53.     int c;                /* character assembly */
  54.     unsigned char *cp;        /* temporary character pointer */
  55.     char *em;            /* error message */
  56.     int i;                /* temporary index */
  57.     int l;                /* length */
  58.     unsigned char *r;        /* result string */
  59. /*
  60.  * Make space for the result.
  61.  */
  62.     if ((r = (unsigned char *)malloc(strlen((char *)s) + 1)) == NULL) {
  63.         (void) fprintf(stderr, "%s: out of string space at %s\n",
  64.             Pname, s);
  65.         return(NULL);
  66.     }
  67. /*
  68.  * Copy the input string to the result, processing '\\' escapes.
  69.  */
  70.     for (cp = r, l = 0; *s;) {
  71.         switch (*s) {
  72.  
  73.         case '\\':
  74.             s++;
  75.             if (*s >= '0' && *s <= '7') {
  76.         /*
  77.          * '\xxx' -- octal form
  78.          */
  79.                 for (c = i = 0; i < 3; i++, s++) {
  80.                     if (*s < '0' || *s > '7') {
  81.                         em = "non-octal char";
  82. bad_string:
  83.                         (void) fprintf(stderr,
  84.                             "%s: %s : %s\n",
  85.                             Pname, em, (char *)r);
  86.                         return(NULL);
  87.                     }
  88.                     c = (c << 3) + *s - '0';
  89.                 }
  90.                 if (c > 0377) {
  91.                     em = "octal char > 0377";
  92.                     goto bad_string;
  93.                 }
  94.                 *cp++ = c;
  95.                 l++;
  96.             } else if (*s == 'x') {
  97.         /*
  98.          * '\xyy' -- hexadecimal form
  99.          */
  100.                 s++;
  101.                 for (c = i = 0; i < 2; i++, s++) {
  102. #if    defined(__STDC__)
  103.                     if ( ! isalpha(*s) && ! isdigit(*s))
  104. #else
  105.                     if ( ! isascii(*s) && ! isalpha(*s)
  106.                     &&   ! isdigit(*s))
  107. #endif
  108.                     {
  109. non_hex_char:
  110.                         em = "non-hex char";
  111.                         goto bad_string;
  112.                     }
  113.                     c = c << 4;
  114.                     if (*s >= '0' && *s <= '9')
  115.                         c += *s - '0';
  116.                     else if ((*s >= 'a' && *s <= 'f')
  117.                          ||  (*s >= 'A' && *s <= 'F'))
  118.                         c += *s + 10 -
  119.                              (isupper(*s) ? 'A' : 'a');
  120.                     else
  121.                         goto non_hex_char;
  122.                 }
  123.                 *cp++ = (unsigned char)c;
  124.                 l++;
  125.             } else if (*s == 'E' || *s == 'e') {
  126.         /*
  127.          * '\E' or '\e' -- ESCape
  128.          */
  129.                 *cp++ = ESC;
  130.                 l++;
  131.                 s++;
  132.             } else if (*s == '\0') {
  133.                 em = "no char after \\";
  134.                 goto bad_string;
  135.             } else {
  136.         /*
  137.          * escaped character (for some reason)
  138.          */
  139.                 *cp++ = *s++;
  140.                 l++;
  141.             }
  142.             break;
  143.     /*
  144.      * Copy a "normal" character.
  145.      */
  146.         default:
  147.             *cp++ = *s++;
  148.             l++;
  149.         }
  150.     }
  151.     *cp = '\0';
  152.     *len = l;
  153.     return(r);
  154. }
  155.  
  156.  
  157. /*
  158.  * Convfont(nm, s, fn, fi) - convert a font for a device
  159.  */
  160.  
  161. static int
  162. Convfont(nm, s, fn, fi)
  163.     char *nm;            /* output device name */
  164.     char *s;            /* font definition string */
  165.     char **fn;            /* font name address */
  166.     unsigned char **fi;        /* initialization string address */
  167. {
  168.     char *cp;            /* temporary character pointer */
  169.     int len;            /* length */
  170. /*
  171.  * Get the font name, allocate space for it and allocate space for
  172.  * a font structure.
  173.  */
  174.     if ((cp = strchr(s, '=')) == NULL) {
  175.         (void) fprintf(stderr, "%s: bad %s font line format: %s\n",
  176.             Pname, nm, s);
  177.         return(0);
  178.     }
  179.     if ((*fn = (char *)malloc(cp - s + 1)) == NULL) {
  180.         (void) fprintf(stderr, "%s: no space for %s font name %s\n",
  181.             Pname, nm, s);
  182.         return(0);
  183.     }
  184.     (void) strncpy(*fn, s, cp - s);
  185.     (*fn)[cp - s] = '\0';
  186. /*
  187.  * Assmble the font initialization string.
  188.  */
  189.     if ((*fi = Convstr(cp + 1, &len)) == NULL)
  190.         return(0);
  191.     return(len);
  192. }
  193.  
  194.  
  195. /*
  196.  * Defdev() - define the output device
  197.  */
  198.  
  199. int
  200. Defdev()
  201. {
  202.     unsigned char *fi = NULL;    /* last font initialization string */
  203.     char *fn = NULL;        /* font name */
  204.     int fd = 0;            /* found-device flag */
  205.     FILE *fs;            /* file stream */
  206.     int err = 0;            /* errror count */
  207.     int i;                /* temporary index */
  208.     int len;            /* length */
  209.     char line[MAXLINE];        /* line buffer */
  210.     char *p;            /* output device configuration file */
  211.     char *s;            /* temporary string pointer */
  212. /*
  213.  * Check for the built-in devices, ANSI, NONE or NORMAL (default).
  214.  */
  215.     Fstr.b = Fstr.i = Fstr.it = Fstr.r = NULL;
  216.     Fstr.bl = Fstr.il = Fstr.itl = Fstr.rl = 0;
  217.     if (Device == NULL || strcasecmp(Device, "normal") == 0) {
  218.         Fontctl = 0;
  219. check_font:
  220.         if (Devfont) {
  221.             (void) fprintf(stderr,
  222.                 "%s: font %s for device %s illegal\n",
  223.                 Pname, Devfont, Device ? Device : "NORMAL");
  224.             return(1);
  225.         }
  226.         return(0);
  227.     }
  228.     Fontctl = 1;
  229.     if (strcasecmp(Device, "ansi") == 0) {
  230.         Fstr.b = Newstr((unsigned char *)"x[7m");
  231.         Fstr.it = Newstr((unsigned char *)"x[4m");
  232.         Fstr.r = Newstr((unsigned char *)"x[0m");
  233.         Fstr.b[0] = Fstr.it[0] = Fstr.r[0] = ESC;
  234.         Fstr.bl = Fstr.itl = Fstr.rl = 4;
  235.         goto check_font;
  236.     }
  237.     if (strcasecmp(Device, "none") == 0)
  238.         goto check_font;
  239. /*
  240.  * If a device configuration file path is supplied, use it.
  241.  */
  242.     if (Devconf)
  243.         p = Devconf;
  244.     else {
  245.  
  246.     /*
  247.      * Use the CAWFLIB environment if it is defined.
  248.      */
  249.         if ((p = getenv("CAWFLIB")) == NULL)    
  250.             p = CAWFLIB;
  251.         len = strlen(p) + 1 + strlen(DEVCONFIG) + 1;
  252.         if ((s = (char *)malloc(len)) == NULL) {
  253.             (void) fprintf(stderr, "%s: no space for %s name\n",
  254.                 Pname, DEVCONFIG);
  255.             return(1);
  256.         }
  257.         (void) sprintf(s, "%s/%s", p, DEVCONFIG);
  258.         p = s;
  259.     }
  260. /*
  261.  * Open the configuration file.
  262.  */
  263. #ifdef    UNIX
  264.     if ((fs = fopen(p, "r")) == NULL)
  265. #else
  266.     if ((fs = fopen(p, "rt")) == NULL)
  267. #endif
  268.     {
  269.         (void) fprintf(stderr, "%s: can't open config file: %s\n",
  270.             Pname, p);
  271.         return(1);
  272.     }
  273.     *line = ' ';
  274. /*
  275.  * Look for a device definition line -- a line that begins with a name.
  276.  */
  277.     while ( ! feof(fs)) {
  278.         if (*line == '\t' || *line == '#' || *line == ' ') {
  279.             (void) fgets(line, MAXLINE, fs);
  280.             continue;
  281.         }
  282.         if ((s = strrchr(line, '\n')) != NULL)
  283.             *s = '\0';
  284.         else
  285.             line[MAXLINE-1] = '\0';
  286.     /*
  287.      * Match device name.
  288.      */
  289.         if (strcmp(Device, line) != 0) {
  290.             (void) fgets(line, MAXLINE, fs);
  291.             continue;
  292.         }
  293.         fd = 1;
  294.     /*
  295.      * Read the parameter lines for the device.
  296.      */
  297.         while (fgets(line, MAXLINE, fs) != NULL) {
  298.             if (*line == ' ') {
  299.                 for (i = 1; line[i] == ' '; i++)
  300.                     ;
  301.             } else if (*line == '\t')
  302.                 i = 1;
  303.             else
  304.                 break;
  305. #if    defined(__STDC__)
  306.             if ( ! isalpha(line[i])
  307. #else
  308.             if ( ! isascii(line[i]) || ! isalpha(line[i])
  309. #endif
  310.             ||   line[i+1] != '=')
  311.                 break;
  312.             if ((s = strrchr(line, '\n')) != NULL)
  313.                 *s = '\0';
  314.             else
  315.                 line[MAXLINE-1] = '\0';
  316.             switch (line[i]) {
  317.         /*
  318.          * \tb=<bolding_string>
  319.          */
  320.             case 'b':
  321.                 if (Fstr.b != NULL) {
  322.                     (void) fprintf(stderr,
  323.                     "%s: dup bold for %s in %s: %s\n",
  324.                     Pname, Device, p, line);
  325.                     (void) free(Fstr.b);
  326.                     Fstr.b = NULL;
  327.                 }
  328.                 if ((Fstr.b = Convstr(&line[i+2], &Fstr.bl))
  329.                 == NULL)
  330.                     err++;
  331.                 break;
  332.         /*
  333.          * \ti=<italicization_string>
  334.          */
  335.             case 'i':
  336.                 if (Fstr.it != NULL) {
  337.                     (void) fprintf(stderr,
  338.                     "%s: dup italic for %s in %s: %s\n",
  339.                     Pname, Device, p, line);
  340.                     (void) free(Fstr.it);
  341.                     Fstr.it = NULL;
  342.                 }
  343.                 if ((Fstr